﻿// -------------------------------------------------------------------------- //
//	文件名		: 	OpenEfficiency.cs
//	创建者		:	xianglinjian
//	创建时间	:	2010-10-20   17:55:32
//	功能描述	:   分析新旧ET在打开时间和内存上的差别; 可附加简单写盘测试
//                  测试重算机制和共享公式写盘后excel读取是否发生错误
// -------------------------------------------------------------------------- //
#if ENABLE_ET_COM
#if ENABLE_EXCEL_COM
#define ENABLE_AutoItX

namespace suite_open_effciency_monitor
{
    using System;
    using System.Xml;
    using System.Collections.Generic;

    public class COpenEffMonitor : suit_base.SuiteBase
    {
        private bool m_bTestSaveAs = false; //  测试EXCEl打开ET另存文件
        private string m_sSamplePath;
        private string m_sExcelPath;
        private string m_sOldEtPath;
        private string m_sNewEtPath;
        private int m_nTimeBound;
        private double m_dbTimePCT;
        private long m_lMemBound;
        private double m_dbMemPCT;
        private autoIt.CAutoIt m_wndKiller;
        private CExpFile m_expFile;
        private CDumpUnAccept m_dumpFile;
        private Dictionary<string, List<tool.CAddInfoHlp.CFileInfo>> m_fileDic;
        private Dictionary<string, tool.CAddInfoHlp.CFileInfo> m_tmpFiles =
            new Dictionary<string, tool.CAddInfoHlp.CFileInfo>();

        public override string GetCommand()
        {
            return ET_Improve.Global.CMD_OPENEFF;
        }

        public override void Call()
        {
            try
            {
                LoadConfig();
                m_fileDic = tool.CAddInfoHlp.GetFolderFiles(m_sSamplePath, ET_Improve.Global.CMD_OPENEFF);
                if (m_bTestSaveAs)
                {
                    excelOp.ExcelOP.RegisterExcel(m_sExcelPath);
                }

                m_wndKiller = new autoIt.CAutoIt();
                m_wndKiller.Start();
 
                m_dumpFile = new CDumpUnAccept();
                m_dumpFile.Begin(m_sSamplePath);
                RunWithOldET();
                RunWithNewET();
                RunAnalyseExport();
                tool.Output.DumpWriteLine(">>>>>>openeff completed!<<<<<<");
                m_dumpFile.End();
            }
            catch (Exception ex)
            {
                tool.Output.DumpWriteLine(ex.ToString());
            }
            finally
            {
                m_wndKiller.Stop();
                m_dumpFile.End();
            }
        }

        protected void LoadConfig()
        {
            const string LOG_ROOT = "OpenEfficiency";
            const string LOG_SAMPLE = "SamplePath";
            const string LOG_PATH = "Path";
            const string LOG_EXCEL = "ExcelPath";
            const string LOG_OLD_ET = "OldEtPath";
            const string LOG_NEW_ET = "NewEtPath";
            const string LOG_ACCEPTED = "Acceptable";
            const string LOG_TIME_BOUND = "TimeBound";
            const string LOG_MEM_BOUND = "MemoryBound";
            const string LOG_TIME_PCT = "TimeFloatPercent";
            const string LOG_MEM_PCT = "MemoryFloatPercent";
            const string LOG_TEST_SAVEAS = "TestSaveAs";

            try
            {
                foreach (XmlNode nodeX in tool.ConfigReader.GetElementList(LOG_ROOT))
                {
                    if(nodeX.Name == LOG_SAMPLE)
                    {
                        m_sSamplePath = nodeX.InnerText;
                    }
                    else if (nodeX.Name == LOG_PATH)
                    {
                        XmlElement ele = (XmlElement)nodeX;
                        m_sExcelPath = ele.GetAttribute(LOG_EXCEL);
                        if (m_sExcelPath.Length == 0)
                        {
                            m_sExcelPath = null;
                        }
                        m_sOldEtPath = ele.GetAttribute(LOG_OLD_ET);
                        m_sNewEtPath = ele.GetAttribute(LOG_NEW_ET);
                    }
                    else if (nodeX.Name == LOG_ACCEPTED)
                    {
                        XmlElement ele = (XmlElement)nodeX;
                        m_nTimeBound = int.Parse(ele.GetAttribute(LOG_TIME_BOUND));
                        m_lMemBound = long.Parse(ele.GetAttribute(LOG_MEM_BOUND));
                        m_dbTimePCT = double.Parse(ele.GetAttribute(LOG_TIME_PCT));
                        m_dbMemPCT = double.Parse(ele.GetAttribute(LOG_MEM_PCT));
                    }
                    else if (nodeX.Name == LOG_TEST_SAVEAS)
                    {
                        m_bTestSaveAs = Boolean.Parse(nodeX.InnerText);
                    }
                }
            }
            catch (System.Exception ex)
            {
                tool.Output.DumpWriteLine(ex.ToString());
                throw ex;
            }
        }

        protected void RunWithOldET()
        {
            try
            {
                etOp.EtOp.ReRegisterET(m_sOldEtPath);
                foreach (string sDir in m_fileDic.Keys)
                {
                    if (CExpFile.IsAllProduced(sDir) || CExpFile.IsOldETProduced(sDir) ||
                        m_fileDic[sDir].Count == 0)
                    {
                        continue;
                    }

                    tool.LogTool.GetInstance().BeginUseLog(sDir, ET_Improve.Global.s_curCmdName);
                    m_expFile = new CExpFile();
                    m_expFile.InitOldET();
                    foreach (tool.CAddInfoHlp.CFileInfo fi in m_fileDic[sDir])
                    {
                        tool.Output.DumpWriteLine(">RunOldET.DoETExpFile: " + fi.FileName + "<");
                        DoETExpFile(true, fi);
                    }
                    m_expFile.Save(sDir);
                    m_expFile = null;
                    tool.LogTool.GetInstance().EndUseLog();
                }
            }
            catch (System.Exception ex)
            {
                tool.Output.DumpWriteLine(">RunWithOldET Exception<");
                throw ex;
            }
        }

        protected void RunWithNewET()
        {
            try
            {
                etOp.EtOp.ReRegisterET(m_sNewEtPath);
                foreach (string sDir in m_fileDic.Keys)
                {
                    if (CExpFile.IsAllProduced(sDir) || CExpFile.IsNewETProduced(sDir) ||
                        m_fileDic[sDir].Count == 0)
                    {
                        continue;
                    }

                    tool.LogTool.GetInstance().BeginUseLog(sDir, ET_Improve.Global.s_curCmdName);
                    m_expFile = new CExpFile();
                    m_expFile.InitNewET();
                    m_tmpFiles.Clear();
                    foreach (tool.CAddInfoHlp.CFileInfo fileInfo in m_fileDic[sDir])
                    {
                        tool.Output.DumpWriteLine(">RunNewET.DoETExpFile: " + fileInfo.FileName + "<");
                        DoETExpFile(false, fileInfo);
                    }
                    m_expFile.Save(sDir);
                    m_expFile = null;

                    if (m_bTestSaveAs)
                    {
                        RunWithExcel();
                    }

                    tool.LogTool.GetInstance().EndUseLog();
                    foreach (string stmp in m_tmpFiles.Keys)
                    {
                        tool.CTmpFileHlp.DeleteTmpFile(stmp);
                    }
                }
            }
            catch (System.Exception ex)
            {
                tool.Output.DumpWriteLine(">RunWithNewET Exception<");
                throw ex;
            }
        }

        protected void DoETExpFile(bool bOldET, tool.CAddInfoHlp.CFileInfo file)
        {
            int nTime = -1;
            long lMem = -1;
            string sTmpFile = null;
            etOp.EtOp pET = new etOp.EtOp();
            try
            {
                m_wndKiller.BeginMonitor(true);
                bool bSaveAs = (!bOldET && m_bTestSaveAs);
                pET.Init(m_wndKiller, true);
                pET.Open(file.FileName, file.Password);
                if (pET.GetTimeMemory(ref nTime, ref lMem))
                {
                    if(bSaveAs)
                    {
                        sTmpFile = pET.SaveAsTmpFile();
                        m_tmpFiles.Add(sTmpFile, file);
                    }
                }
                m_expFile.AddExpNode(bOldET, file.FileName, nTime, lMem);
                pET.Close();
            }
            catch (tool.ETImpException ex)
            {
                if (ex.FileName == null)
                {
                    ex.FileName = file.FileName;
                }
                ex.AddLog();
            }
            catch (System.Exception ex)
            {
                tool.LogTool.GetInstance().AddLog(tool.LogTool.LOG_TYPE.EXCEPTION, file.FileName, null, ex);
            }
            finally
            {
                m_wndKiller.EndMonitor();
                etOp.EtOp.DestoryET(ref pET);
            }
        }

        protected void RunWithExcel()
        {
            try
            {
                tool.Output.DumpWriteLine(">RunWithExcel<");
                foreach (string sKey in m_tmpFiles.Keys)
                {
                    tool.CAddInfoHlp.CFileInfo fi = m_tmpFiles[sKey];
                    DoExcelOpenTest(sKey, m_tmpFiles[sKey]);
                }
            }
            catch (System.Exception ex)
            {
                throw new tool.ETImpException(tool.LogTool.LOG_TYPE.ERROR, null, "RunWithExcel", ex);
            }
        }

        // 如果Excel打开重算且excel另存再次打开却不重算，那么就有问题了
        protected void DoExcelOpenTest(string sTmpFile, tool.CAddInfoHlp.CFileInfo fi)
        {
            excelOp.ExcelOP pExcel1 = null;
            excelOp.ExcelOP pExcel2 = null;
            string sSecondTmp = null;
            try
            {
                tool.Output.DumpWriteLine(">Excel open tmpfile first<");
                pExcel1 = new excelOp.ExcelOP();
                pExcel1.Init(m_wndKiller, true);
                pExcel1.Open(sTmpFile, fi.Password, false);
                if (!pExcel1.IsRecalculate())
                {
                    excelOp.ExcelOP.DestoryExcelOp(ref pExcel1);
                    return;
                }
                
                sSecondTmp = tool.CTmpFileHlp.GetSystemTmpName(fi.FileName);
                pExcel1.SaveAs(sSecondTmp);
                excelOp.ExcelOP.DestoryExcelOp(ref pExcel1);

                tool.Output.DumpWriteLine(">Excel open tmpfile second<");
                pExcel2 = new excelOp.ExcelOP();
                pExcel2.Init(m_wndKiller, true);
                pExcel2.Open(sSecondTmp, fi.Password);
                if(!pExcel2.IsRecalculate())
                {
                    tool.LogTool.GetInstance().AddLog(tool.LogTool.LOG_TYPE.FILE_ERROR, fi.FileName, "DoTestFileeError", null);
                }
                excelOp.ExcelOP.DestoryExcelOp(ref pExcel2);
            }
            catch (System.Exception ex)
            {
                tool.LogTool.GetInstance().AddLog(tool.LogTool.LOG_TYPE.ERROR, fi.FileName, "DoExcelOpenTest异常", ex);
            }
            finally
            {
                excelOp.ExcelOP.DestoryExcelOp(ref pExcel1);
                excelOp.ExcelOP.DestoryExcelOp(ref pExcel2);
                tool.CTmpFileHlp.DeleteTmpFile(sSecondTmp);
            }
        }

        protected void RunAnalyseExport()
        {
            try
            {
                foreach (string sDir in m_fileDic.Keys)
                {
                    if (CExpFile.IsAllProduced(sDir) || m_fileDic[sDir].Count == 0)
                    {
                        continue;
                    }
                    if (!CExpFile.IsOldETProduced(sDir) || !CExpFile.IsNewETProduced(sDir))
                    {
                        continue;
                    }
                    tool.LogTool.GetInstance().BeginUseLog(sDir, ET_Improve.Global.s_curCmdName);
                    m_expFile = new CExpFile();
                    m_expFile.InitExpFile();

                    AnalyseExport(sDir);

                    m_expFile.Save(sDir);
                    m_expFile = null;
                    tool.LogTool.GetInstance().EndUseLog();
                }
            }
            catch (tool.ETImpException ex)
            {
                ex.AddLog();
            }
            catch (System.Exception ex)
            {
                tool.LogTool.GetInstance().AddLog(tool.LogTool.LOG_TYPE.ERROR, null, "分析导出文件失败", ex);
            }
        }

        protected void AnalyseExport(string sDir)
        {
            try
            {
                CExpFile oldExp = new CExpFile();
                oldExp.LoadExpData(true, sDir);
                CExpFile newExp = new CExpFile();
                newExp.LoadExpData(false, sDir);
                foreach (tool.CAddInfoHlp.CFileInfo fi in m_fileDic[sDir])
                {
                    int oldTm = -1;
                    int newTm = -1;
                    long oldMem = -1;
                    long newMem = -1;
                    // 只要存在一个就行
                    bool bOldExist = oldExp.GetEffData(fi.FileName, true, ref oldTm, ref oldMem);
                    bool bNewExist = newExp.GetEffData(fi.FileName, false, ref newTm, ref newMem);
                    if( bOldExist || bNewExist)
                    {
                        tool.Output.DumpWriteLine(">AnalyseExport : " + fi.FileName);
                        ComparePerf(fi.FileName, oldTm, newTm, oldMem, newMem);
                    }
                }
            }
            catch (Exception ex)
            {
                throw new tool.ETImpException(tool.LogTool.LOG_TYPE.ERROR, null, "分析导出的比较文件失败", ex);
            }
        }

        protected bool IsTimeAccepted(int oldTm, int newTm)
        {
            System.Diagnostics.Debug.Assert(oldTm != -1 && newTm != -1);
            if(oldTm == -1 || newTm == -1)
            {
                return false;
            }
            if(IsOutOfTimeBound(oldTm, newTm) &&
                IsOutOfTimePercent(oldTm, newTm))
            {
                return false;
            }

            return true;
        }

        protected bool IsMemoryAccepted(long oldMem, long newMem)
        {
            System.Diagnostics.Debug.Assert(oldMem != -1 && newMem != -1);
            if (oldMem == -1 || newMem == -1)
            {
                return false;
            }
            if (IsOutOfMemBound(oldMem, newMem) && 
                IsOutOfMemPercent(oldMem, newMem))
            {
                return false;
            }
            return true;
        }

        protected void ComparePerf(string sFile, int oldTm, int newTm,
                        long oldMem, long newMem)
        {
            bool bTimeAcc = false;
            bool bMemAcc = false;
            if(oldTm != -1 && newTm != -1)
            {
                bTimeAcc = IsTimeAccepted(oldTm, newTm);
            }
            if(!bTimeAcc)
            {
                AddUnAccTimeLog(sFile, oldTm, newTm);
            }
            
            if(oldMem != -1 && newMem != -1)
            {
                bMemAcc = IsMemoryAccepted(oldMem, newMem);
            }
            if (!bMemAcc)
            {
                AddUnAccMemLog(sFile, oldMem, newMem);
            }

            m_expFile.AddResultData(sFile, oldTm, newTm, oldMem, newMem, bTimeAcc, bMemAcc);
        }

        private bool IsOutOfTimeBound(int t1, int t2)
        {
            return (System.Math.Abs(t1 - t2) > m_nTimeBound);
        }

        private bool IsOutOfMemBound(long m1, long m2)
        {
            return (System.Math.Abs(m1 - m2) > m_lMemBound);
        }

        private bool IsOutOfTimePercent(int oT, int nT)
        {
            double dT = System.Math.Abs(nT - oT);
            dT /= (double)oT;
            return (dT > m_dbTimePCT);
        }

        private bool IsOutOfMemPercent(long oM, long nM)
        {
            double dT = System.Math.Abs(nM - oM);
            dT /= (double)oM;
            return (dT > m_dbMemPCT);
        }

        protected void AddUnAccMemLog(string sFileName, long lOld, long lNew)
        {
            m_dumpFile.AddMemory(lOld, lNew, sFileName);
            tool.LogTool.GetInstance().AddLog(tool.LogTool.LOG_TYPE.MEM_UNACCEPTED,
                sFileName, string.Format("{0} vs {1}", lOld, lNew), null);
        }

        protected void AddUnAccTimeLog(string sFileName, int nOld, int nNew)
        {
            m_dumpFile.AddTime(nOld, nNew, sFileName);
            tool.LogTool.GetInstance().AddLog(tool.LogTool.LOG_TYPE.TIME_UNACCEPTED,
                sFileName, string.Format("{0} vs {1}", nOld, nNew), null);
        }
    }

    // 导出文件.老ET先全跑一遍，然后新ET跑一遍，然后再分析一遍
    internal class CExpFile
    {
        protected enum FILE_TYPE
        {
            OLD_ET,
            NEW_ET,
            RESULT,
        }
        private FILE_TYPE m_fileType;
        private XmlDocument m_expXml;
        private XmlElement m_rootNode;
        private const string EXP_OLD = "Old";
        private const string EXP_NEW = "New";
        private const string EXP_TIME = "time";
        private const string EXP_MEM = "memory";
        private const string m_sOldFile = "exp_openeff_old.xml";
        private const string m_sNewFile = "exp_openeff_new.xml";
        private const string m_sResultFile = "exp_openeff.xml";

        //// 下面是新老ET文件操作
        public static bool IsOldETProduced(string sCurDir)
        {
            tool.CAddInfoHlp.ValidDirectory(ref sCurDir);
            string spath = sCurDir + m_sOldFile;
            return System.IO.File.Exists(spath);
        }

        public static bool IsNewETProduced(string sCurDir)
        {
            tool.CAddInfoHlp.ValidDirectory(ref sCurDir);
            string spath = sCurDir + m_sNewFile;
            return System.IO.File.Exists(spath);
        }

        public static bool IsAllProduced(string sCurDir)
        {
            tool.CAddInfoHlp.ValidDirectory(ref sCurDir);
            string spath = sCurDir + m_sResultFile;
            return System.IO.File.Exists(spath);
        }

        protected string GetExpSuffix(FILE_TYPE _type)
        {
            string sSuffix = "";
            switch (_type)
            {
                case FILE_TYPE.OLD_ET: sSuffix = m_sOldFile; break;
                case FILE_TYPE.NEW_ET: sSuffix = m_sNewFile; break;
                case FILE_TYPE.RESULT: sSuffix = m_sResultFile; break;
            }
            return sSuffix;
        }

        protected bool CreateExpFile()
        {
            try
            {
                m_expXml = new XmlDocument();
                XmlDeclaration xmlDec = m_expXml.CreateXmlDeclaration("1.0", "UTF-8", null);


                m_expXml.InsertBefore(xmlDec, m_expXml.DocumentElement);
                m_rootNode = m_expXml.CreateElement("", "root", "");
                m_expXml.AppendChild(m_rootNode);

                XmlComment comment = m_expXml.CreateComment(tool.CTimer.GetTimeComment());
                m_rootNode.AppendChild(comment);
                return true;
            }
            catch (System.Exception ex)
            {
                tool.Output.DumpWriteLine(ex.ToString());
                tool.LogTool.GetInstance().AddLog(tool.LogTool.LOG_TYPE.ERROR, null, "CreateExpFile失败", ex);
                return false;
            }
        }

        public bool InitOldET()
        {
            m_fileType = FILE_TYPE.OLD_ET;
            return CreateExpFile();
        }

        public bool InitNewET()
        {
            m_fileType = FILE_TYPE.NEW_ET;
            return CreateExpFile();
        }

        public bool InitExpFile()
        {
            m_fileType = FILE_TYPE.RESULT;
            return CreateExpFile();
        }

        public void Save(string sDir)
        {
            try
            {
                tool.CAddInfoHlp.ValidDirectory(ref sDir);
                string sPath = sDir + GetExpSuffix(m_fileType);
                m_expXml.Save(sPath);
                m_rootNode = null;
                m_expXml = null;
            }
            catch (System.Exception ex)
            {
                throw ex;
            }
        }

        public void AddExpNode(bool bOldET, string sFile, int nTime, long lMem)
        {
            try
            {
                string sFileName = System.IO.Path.GetFileName(sFile);
                XmlElement node = m_expXml.CreateElement("", "File", "");
                node.SetAttribute("Path", sFileName);

                XmlElement tm = m_expXml.CreateElement("", EXP_TIME, "");
                if (bOldET)
                {
                    tm.SetAttribute(EXP_OLD, nTime.ToString());
                }
                else
                {
                    tm.SetAttribute(EXP_NEW, nTime.ToString());
                }
                node.AppendChild(tm);

                XmlElement mem = m_expXml.CreateElement("", EXP_MEM, "");
                if (bOldET)
                {
                    mem.SetAttribute(EXP_OLD, lMem.ToString());
                }
                else
                {
                    mem.SetAttribute(EXP_NEW, lMem.ToString());
                }
                node.AppendChild(mem);
                m_rootNode.AppendChild(node);
            }
            catch (System.Exception ex)
            {
                throw new tool.ETImpException(tool.LogTool.LOG_TYPE.ERROR, sFile, "AddExprotFile失败: ", ex);
            }
        }

        protected bool IsNodeExist(string sFile, ref XmlNode node)
        {
            try
            {
                string sFind = String.Format("root/File[@Path='{0:g}']", sFile);
                node = m_expXml.SelectSingleNode(sFind);
                if (node == null)
                {
                    return false;
                }
                return true;
            }
            catch (System.Exception ex)
            {
                throw new tool.ETImpException(tool.LogTool.LOG_TYPE.ERROR, sFile, null, ex);
            }
        }

        public void LoadExpData(bool bOldET, string sDir)
        {
            try
            {
                m_expXml = new XmlDocument();
                tool.CAddInfoHlp.ValidDirectory(ref sDir);
                string sFileName = sDir + GetExpSuffix(bOldET ? FILE_TYPE.OLD_ET : FILE_TYPE.NEW_ET);
                m_expXml.Load(sFileName);
                m_rootNode = (XmlElement)m_expXml.SelectSingleNode("root");
            }
            catch (System.Exception ex)
            {
                tool.Output.DumpWriteLine("加载exp xml失败");
                throw ex;
            }
        }

        protected void GetEffTime(XmlElement xe, bool bOldET, ref int nTime)
        {
            if(xe == null)
            {
                return;
            }

            if (bOldET)
            {
                nTime = int.Parse(xe.Attributes[EXP_OLD].Value);
            }
            else
            {
                nTime = int.Parse(xe.Attributes[EXP_NEW].Value);
            }
        }

        protected void GetEffMemory(XmlElement xe, bool bOldET, ref long lMem)
        {
            if (xe == null)
            {
                return;
            }
            if (bOldET)
            {
                lMem = long.Parse(xe.Attributes[EXP_OLD].Value);
            }
            else
            {
                lMem = long.Parse(xe.Attributes[EXP_NEW].Value);
            }
        }

        // 是否存在该节点
        public bool GetEffData(string sFile, bool bOldET, ref int nTime, ref long lMem)
        {
            XmlNode node = null;
            string sFileName = System.IO.Path.GetFileName(sFile);
            if (!IsNodeExist(sFileName, ref node))
            {
                return false;
            }

            string sPath = ((XmlElement)node).GetAttribute("Path");
            XmlElement xeTm = (XmlElement)node.SelectSingleNode(EXP_TIME);
            GetEffTime(xeTm, bOldET, ref nTime);            
            XmlElement xeMem = (XmlElement)node.SelectSingleNode(EXP_MEM);
            GetEffMemory(xeMem, bOldET, ref lMem);

            return true;
        }

        public void AddResultData(string sFileName, int nOldTm, int nNewTm, long lOldMem,
            long lNewMem, bool bTimeAccept, bool bMemAccept)
        {
            try
            {
                XmlElement node = m_expXml.CreateElement("", "File", "");
                node.SetAttribute("Path", sFileName);
                XmlElement tm = m_expXml.CreateElement("", EXP_TIME, "");
                tm.SetAttribute(EXP_OLD, nOldTm.ToString());
                tm.SetAttribute(EXP_NEW, nNewTm.ToString());
                tm.SetAttribute("accepted", bTimeAccept.ToString());
                node.AppendChild(tm);

                XmlElement mem = m_expXml.CreateElement("", EXP_MEM, "");
                mem.SetAttribute(EXP_OLD, lOldMem.ToString());
                mem.SetAttribute(EXP_NEW, lNewMem.ToString());
                mem.SetAttribute("accepted", bMemAccept.ToString());
                node.AppendChild(mem);

                m_rootNode.AppendChild(node);
            }
            catch (Exception ex)
            {
                throw new tool.ETImpException(tool.LogTool.LOG_TYPE.ERROR, sFileName, "AddResultExprotFile失败: ", ex);
            }
        }
    }

    internal class CDumpUnAccept
    {
        private System.IO.StreamWriter m_fileOp;
        private string m_sOutputFile;
        private int m_nAddPart;
        private int m_nCurLine;
        private const int MAX_LINE = 60000;
        public void Begin(string sPath)
        {
            try
            {
                string sFileName = DateTime.Now.ToString("yyyy-MM-dd_HH-mm");
                tool.CAddInfoHlp.ValidDirectory(ref sPath);
                m_sOutputFile = sPath + "dump_openeff_" + sFileName;
                m_nAddPart = 0;
                InitStream();
            }
            catch (System.Exception ex)
            {
                Console.WriteLine(ex.ToString());
            }
        }

        protected void InitStream()
        {
            string sOutput = m_sOutputFile;
            if(m_nAddPart > 0)
            {
                sOutput = m_sOutputFile + string.Format("_part{0}", m_nAddPart);
            }
            sOutput += ".txt";
            m_nCurLine = 0;
            m_fileOp = System.IO.File.AppendText(sOutput);
            m_fileOp.AutoFlush = true;
        }

        protected void PreWriteLine()
        {
            if(m_nCurLine++ < MAX_LINE)
            {
                return;
            }
            ++m_nAddPart;
            SaveCache();
            InitStream();
        }

        protected void SaveCache()
        {
            try
            {
                m_fileOp.Close();
                m_fileOp = null;
            }
            catch (System.Exception ex)
            {
                Console.WriteLine(ex.ToString());
            }
        }

        public void AddMemory(long lOld, long lNew, string sFileName)
        {
            try
            {
                PreWriteLine();
                m_fileOp.WriteLine(string.Format("{0}\t{1}\t{2}\t{3}", tool.LogTool.LOG_TYPE.MEM_UNACCEPTED,
                lOld, lNew, sFileName));
            }
            catch (System.Exception ex)
            {
                Console.WriteLine(ex.ToString());
            }
        }

        public void AddTime(int nOld, int nNew, string sFileName)
        {
            try
            {
                PreWriteLine();
                m_fileOp.WriteLine(string.Format("{0}\t{1}\t{2}\t{3}", tool.LogTool.LOG_TYPE.TIME_UNACCEPTED,
                nOld, nNew, sFileName));
            }
            catch (System.Exception ex)
            {
                Console.WriteLine(ex.ToString());
            }
        }

        public void End()
        {
            if(m_fileOp != null)
            {
                SaveCache();
            }
        }
    }
}

#endif // #if ENABLE_EXCEL_COM
#endif // #if ENABLE_ET_COM